package m.system.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import m.common.action.Action;
import m.common.action.RequestMeta;
import m.common.action.RequestParam;
import m.system.exception.MException;

import java.lang.reflect.Method;
import java.util.*;

public class ActionUtil {
	private static final Map<Class<? extends Action>,Method[]> requestMap=new HashMap<>();
	private static final Map<String,RequestParam> paramMap=new HashMap<>();
	/**
	 * 获取action请求注解对应方法的参数
	 *  actionClass
	 *  actionMethod
	 *  method
	 * 
	 *  MException
	 */
	public static RequestParam getRequestParamList(Class<? extends Action> actionClass, String actionMethod, String method) throws MException{
		Method[] ms=requestMap.get(actionClass);
		if(null==ms) {
			ms=ClassUtil.getDeclaredMethods(actionClass);
			requestMap.put(actionClass, ms);
		}
		String key=actionClass.getName()+actionMethod+method;
		RequestParam map=paramMap.get(key);
		if(null==map) {
			map= new RequestParam();
			for(Method m : ms) {
				if(m.getName().equals(actionMethod)) {
					RequestMeta rm=m.getAnnotation(RequestMeta.class);
					if(null!=rm) {
						map.setLogTitle(rm.logTitle());
						map.setLogDescription(rm.logDescription());
						map.setTransaction(rm.transaction());
						if(rm.method().toUpperCase().contains(method.toUpperCase())) {
							Class<?>[] paramTypes = m.getParameterTypes();
							String[] pns=rm.params();
							if(pns.length!=paramTypes.length) throw new MException(ActionUtil.class, "RequestMeta注解参数个数错误");
							for(int i=0;i<pns.length;i++) {
								map.getParamList().put(pns[i], paramTypes[i]);
							}
						}
					}
				}
			}
			paramMap.put(key, map);
		}
		return map;
	}
	public static void main(String[] a) throws MException, ClassNotFoundException {
//		SystemUtil.println("342w".matches("[0-9]*"));
		JSONObject json=new JSONObject();
		fillJSONObject(json, "aa", "12");
		fillJSONObject(json, "a[1]", "22");
		fillJSONObject(json, "a[4]", "22");
		fillJSONObject(json, "ab[sd]", "22");
		SystemUtil.println(ObjectUtil.toString(json));
		SystemUtil.println(ActionUtil.getInAttribute(json,"ab.sd"));
	}
	/**
	 * 把putData合并到data里
	 *  data
	 *  putData
	 */
	public static void fillJSONObject(JSONObject data,JSONObject putData) {
		for(String key : putData.keySet()) {
			Object dd=data.get(key);
			if(dd instanceof JSONObject) {
				fillJSONObject((JSONObject)dd, putData.getJSONObject(key));
			}else if(dd instanceof JSONArray) {
				((JSONArray)dd).addAll(putData.getJSONArray(key));
			}else {
				data.put(key, putData.get(key));
			}
		}
	}
	public static void fillJSONObject(JSONObject data, String name, String value) {
		boolean flag=true;
		int index=0;
		String[] arr=name.split("");
		for(int i=0;i<arr.length;i++){
			if(arr[i].equals("[")) flag=false;
			else if(arr[i].equals("]")) flag=true;
			if(flag&&arr[i].equals(".")){
				index=i;
				break;
			}
		}
		if(index>0){
			String f1=name.substring(0,index);
			String f2=name.substring(f1.length()+1);
			if(f1.contains("[") &&f1.indexOf("]")==f1.length()-1){
				String nm=f1.substring(0,f1.indexOf("["));
				String ni=f1.substring(nm.length()+1,f1.length()-1);
				if(!ni.matches("[0-9]*")){
					if(null==data.get(nm)) data.put(nm,new JSONObject());
					fillJSONObject((JSONObject)data.get(nm),ni+"."+f2,value);
				}else{
					if(null==data.get(nm)) data.put(nm,new JSONArray());
					int n=Integer.parseInt(ni);
					JSONArray ls=(JSONArray)data.get(nm);
					for(int i=1;i<=n+1;i++){
						if(ls.size()<i) ls.add(new JSONObject());
					}
					fillJSONObject((JSONObject)ls.get(n),f2,value);
				}
			}else{
				if(null==data.get(f1)) data.put(f1,new JSONObject());
				fillJSONObject((JSONObject)data.get(f1),f2,value);
			}
		}else{
			if(name.contains("[") && name.indexOf("]")== name.length()-1){
				String nm= name.substring(0, name.indexOf("["));
				String ni= name.substring(nm.length()+1, name.length()-1);
				SystemUtil.println(nm+"--"+ni);
				if(!ni.matches("[0-9]*")){
					if(null==data.get(nm)) data.put(nm,new JSONObject());
					((JSONObject)data.get(nm)).put(ni, value);
				}else{
					if(null==data.get(nm)) data.put(nm,new JSONArray());
					JSONArray list = (JSONArray)data.get(nm);
					if(StringUtil.isSpace(ni)) {
						String[] strs=value.split(",");
						((List<Object>) list).addAll(Arrays.asList(strs));
					}else {
						int n=Integer.parseInt(ni);
						for(int i=0;i<=n+1;i++){
							if(((List<Object>) list).size()<i) ((List<Object>) list).add(null);
						}
						((List<Object>) list).set(n, value);
					}
				}
			}else{
				data.put(name, value);
			}
		}
	}

	public static Object getInAttribute(Object action,String paramName) throws ClassNotFoundException, MException{
		String[] paramNames=paramName.split("\\.");
		if(paramNames.length>1){
			Object obj=ClassUtil.getFieldValue(action, paramNames[0]);
			if(null!=obj){
				return getInAttribute(obj, paramName.substring(paramName.indexOf(".")+1));
			}else{
				return null;
			}
		}else{
			return ClassUtil.getFieldValue(action, paramName);
		}
	}

}
